package com.csaba.swing.gui.otp;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JCheckBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JSeparator;
import javax.swing.JTextField;

import com.csaba.connector.model.Customer;
import com.csaba.connector.otp.OTPLoginService;
import com.csaba.swing.gui.login.AbstractLoginPage;
import com.csaba.swing.gui.login.LoginDetails;
import com.csaba.swing.gui.login.LoginWizardModel;
import com.csaba.swing.gui.util.MaxLengthDocument;
import com.csaba.swing.gui.util.RegExpDocument;
import com.csaba.swing.gui.wizard.WizardContext;
import com.csaba.swing.gui.wizard.WizardDialog;
import com.csaba.util.I18N;

@SuppressWarnings( "serial" )
public class OTPLoginPage extends AbstractLoginPage
{
	private static final String LD_PASSWORD = "password"; //$NON-NLS-1$

	private JTextField loginIdField;
	private JPasswordField passwordField;
	private JCheckBox savePassword;
	private JTextField account1Field;
	private JTextField account2Field;
	private JTextField account3Field;

	@Override
	public void init( final WizardContext context )
	{
		super.init(context);

		add(new JLabel(I18N.getString(this, "OTPLoginPage.loginId"))); //$NON-NLS-1$
		add(loginIdField = new JTextField(
				new RegExpDocument("[0-9]*", OTPLoginService.LOGINID_LENGTH), "", OTPLoginService.LOGINID_LENGTH)); //$NON-NLS-1$ //$NON-NLS-2$

		add(new JLabel(I18N.getString(this, "OTPLoginPage.password"))); //$NON-NLS-1$
		add(passwordField = new JPasswordField(new MaxLengthDocument(OTPLoginService.PASSWORD_LENGTH),
				"", OTPLoginService.PASSWORD_LENGTH)); //$NON-NLS-1$

		add(new JSeparator());
		add(savePassword = new JCheckBox(I18N.getString(this, "OTPLoginPage.savePassword"))); //$NON-NLS-1$

		add(new JLabel(I18N.getString(this, "OTPLoginPage.account"))); //$NON-NLS-1$

		final JPanel accountPanel = new JPanel();
		accountPanel.add(new JLabel(OTPLoginService.ACCOUNT_PREFIX));
		accountPanel.add(account1Field = new JTextField(
				new RegExpDocument("[0-9]*", OTPLoginService.ACC1_LENGTH), "", OTPLoginService.ACC1_LENGTH)); //$NON-NLS-1$ //$NON-NLS-2$
		accountPanel.add(new JLabel("-")); //$NON-NLS-1$
		accountPanel.add(account2Field = new JTextField(
				new RegExpDocument("[0-9]*", OTPLoginService.ACC2_LENGTH), "", OTPLoginService.ACC2_LENGTH)); //$NON-NLS-1$ //$NON-NLS-2$
		accountPanel.add(new JLabel("-")); //$NON-NLS-1$
		accountPanel.add(account3Field = new JTextField(
				new RegExpDocument("[0-9]*", OTPLoginService.ACC3_LENGTH), "", OTPLoginService.ACC3_LENGTH)); //$NON-NLS-1$ //$NON-NLS-2$

		addChangeListener(loginIdField);
		addChangeListener(passwordField);
		addChangeListener(account1Field);
		addChangeListener(account2Field);
		addChangeListener(account3Field);

		final ActionListener autoForward = new ActionListener()
		{

			@Override
			public void actionPerformed( final ActionEvent e )
			{
				context.getDialog().finishPressed();
			}
		};
		loginIdField.addActionListener(autoForward);
		passwordField.addActionListener(autoForward);
		account1Field.addActionListener(autoForward);
		account2Field.addActionListener(autoForward);
		account3Field.addActionListener(autoForward);

		add(accountPanel);
	}

	@Override
	public boolean leave( final int action )
	{
		if ( action == ACTION_FINISH )
		{
			final Customer customer = new Customer();
			customer.setLoginId(loginIdField.getText());
			customer.setPassword(new String(passwordField.getPassword()));
			customer.setRemoteProperty(OTPLoginService.RP_ACCOUNT1, OTPLoginService.ACCOUNT_PREFIX
					+ account1Field.getText());
			customer.setRemoteProperty(OTPLoginService.RP_ACCOUNT2, account2Field.getText());
			customer.setRemoteProperty(OTPLoginService.RP_ACCOUNT3, account3Field.getText());

			return doLogin(customer);
		}
		return true;
	}

	@Override
	protected void updateMessage( final Component component )
	{
		super.updateMessage(component);

		final WizardDialog dialog = context.getDialog();
		boolean ready = true;
		if ( loginIdField.getText().length() < OTPLoginService.LOGINID_MIN_LENGTH )
		{
			dialog.setWarning(I18N.getString(this, "OTPLoginPage.msg.validLoginId")); //$NON-NLS-1$
			ready = false;
		}
		else if ( passwordField.getPassword().length < 1 )
		{
			dialog.setWarning(I18N.getString(this, "OTPLoginPage.msg.validPassword")); //$NON-NLS-1$
			ready = false;
		}
		else if ( ( account1Field.getText().length() < OTPLoginService.ACC1_LENGTH )
				|| ( account2Field.getText().length() < OTPLoginService.ACC2_LENGTH )
				|| ( account3Field.getText().length() > 0 && account3Field.getText().length() < OTPLoginService.ACC3_LENGTH ) )
		{
			dialog.setWarning(I18N.getString(this, "OTPLoginPage.msg.validAccount")); //$NON-NLS-1$
			ready = false;
		}

		//field automation
		if ( component == passwordField && passwordField.getPassword().length == OTPLoginService.PASSWORD_LENGTH )
			account1Field.requestFocus();
		if ( component == account1Field && account1Field.getText().length() == OTPLoginService.ACC1_LENGTH )
			account2Field.requestFocus();
		if ( component == account2Field && account2Field.getText().length() == OTPLoginService.ACC2_LENGTH )
			account3Field.requestFocus();

		if ( ready )
		{
			dialog.clearMessage();
		}
		dialog.setReady(ready);
	}

	@Override
	public void updateView()
	{
		super.updateView();

		savePassword.setEnabled(( (LoginWizardModel) context.getWizardModel() ).isSaveDetails());
		if ( !savePassword.isEnabled() )
			savePassword.setSelected(false);
	}

	@Override
	protected LoginDetails getDetailsToSave( final Customer customer )
	{
		final LoginDetails details = new LoginDetails(customer.getBank().getName(), customer.getLoginId());
		if ( savePassword.isSelected() )
			details.put(LD_PASSWORD, customer.getPassword());

		details.put(OTPLoginService.RP_ACCOUNT1, (String) customer.getRemoteProperty(OTPLoginService.RP_ACCOUNT1));
		details.put(OTPLoginService.RP_ACCOUNT2, (String) customer.getRemoteProperty(OTPLoginService.RP_ACCOUNT2));
		details.put(OTPLoginService.RP_ACCOUNT3, (String) customer.getRemoteProperty(OTPLoginService.RP_ACCOUNT3));

		return details;
	}

	@Override
	protected void setSavedDetails( final LoginDetails details )
	{
		loginIdField.setText(details.getLoginId());

		final String password = details.get(LD_PASSWORD);
		passwordField.setText(password);
		savePassword.setSelected(password != null);

		String account1 = details.get(OTPLoginService.RP_ACCOUNT1);
		if ( account1 != null && account1.startsWith(OTPLoginService.ACCOUNT_PREFIX) )
		{
			account1 = account1.substring(OTPLoginService.ACCOUNT_PREFIX.length());
		}
		account1Field.setText(account1);
		account2Field.setText(details.get(OTPLoginService.RP_ACCOUNT2));
		account3Field.setText(details.get(OTPLoginService.RP_ACCOUNT3));
	}
}
